/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Main.java
 *
 * Created on 16/09/2009, 12:22:59 PM
 */
package simulacion.interfaz;

import java.awt.Dialog.ModalExclusionType;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker.StateValue;
import javax.swing.UIManager;
import org.netbeans.api.visual.widget.Widget;
import org.openide.util.Exceptions;
import problema.mochila.EjercicioMochila;
import problema.viajero.EjercicioViajero;
import problema.viajero.EsquemaViajero;
import problema.viajero.Punto;
import problema.viajero.SolucionViajero;
import simulacion.Configuracion;
import simulacion.Util;
import simulacion.interfaz.mochila.FiltroKNP;
import simulacion.interfaz.mochila.MochilaUI;
import simulacion.interfaz.viajero.Arco;
import simulacion.interfaz.viajero.FiltroTSP;
import simulacion.interfaz.viajero.GrafoViajeroScene;
import simulacion.simulatedAnnealing.Ejercicio;

/**
 *
 * @author John Arevalo
 *
 */
public class Simulated extends javax.swing.JFrame {

    /** Creates new form Main */
    private Ejercicio ejercicio;
    private GrafoViajeroScene grafoViajero;
    private String estado;
    private Configuracion configuracion;

    public Simulated() throws IOException {
        configuracion = new Configuracion();
        initComponents();
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
        labelEstado.setText(estado);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        barraHerramientas = new javax.swing.JToolBar();
        botonAbrirArchivo = new javax.swing.JButton();
        botonEjecutar = new javax.swing.JButton();
        botonGraficar = new javax.swing.JButton();
        scrollPanelDespliegue = new javax.swing.JScrollPane();
        panelDespliegue = new javax.swing.JPanel();
        barraEstado = new javax.swing.JToolBar();
        labelEstado = new javax.swing.JLabel();
        barraProgreso = new javax.swing.JProgressBar();
        barraMenu = new javax.swing.JMenuBar();
        menuArchivo = new javax.swing.JMenu();
        menuAbrirArchivo = new javax.swing.JMenuItem();
        menuSalir = new javax.swing.JMenuItem();
        menuEdicion = new javax.swing.JMenu();
        menuEjecutar = new javax.swing.JMenuItem();
        menuGraficar = new javax.swing.JMenuItem();
        menuPreferencias = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Algoritmos de Simulacion");
        getContentPane().setLayout(new java.awt.GridBagLayout());

        barraHerramientas.setFloatable(false);
        barraHerramientas.setRollover(true);

        botonAbrirArchivo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simulacion/interfaz/imagenes/abrirarchivo.png"))); // NOI18N
        botonAbrirArchivo.setToolTipText("Abrir Archivo...");
        botonAbrirArchivo.setFocusable(false);
        botonAbrirArchivo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        botonAbrirArchivo.setMargin(new java.awt.Insets(10, 10, 10, 10));
        botonAbrirArchivo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        botonAbrirArchivo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonAbrirArchivoActionPerformed(evt);
            }
        });
        barraHerramientas.add(botonAbrirArchivo);

        botonEjecutar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simulacion/interfaz/imagenes/ejecutar.png"))); // NOI18N
        botonEjecutar.setToolTipText("Ejecutar");
        botonEjecutar.setFocusable(false);
        botonEjecutar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        botonEjecutar.setMargin(new java.awt.Insets(10, 10, 10, 10));
        botonEjecutar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        botonEjecutar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonEjecutarActionPerformed(evt);
            }
        });
        barraHerramientas.add(botonEjecutar);

        botonGraficar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/simulacion/interfaz/imagenes/grafica.png"))); // NOI18N
        botonGraficar.setToolTipText("Graficar");
        botonGraficar.setFocusable(false);
        botonGraficar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        botonGraficar.setMargin(new java.awt.Insets(10, 10, 10, 10));
        botonGraficar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        botonGraficar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonGraficarActionPerformed(evt);
            }
        });
        barraHerramientas.add(botonGraficar);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        getContentPane().add(barraHerramientas, gridBagConstraints);

        panelDespliegue.setLayout(new java.awt.BorderLayout());
        scrollPanelDespliegue.setViewportView(panelDespliegue);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(scrollPanelDespliegue, gridBagConstraints);

        barraEstado.setRollover(true);
        barraEstado.add(labelEstado);

        barraProgreso.setStringPainted(true);
        barraEstado.add(barraProgreso);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        getContentPane().add(barraEstado, gridBagConstraints);

        menuArchivo.setText("Archivo");

        menuAbrirArchivo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        menuAbrirArchivo.setText("Abrir Archivo...");
        menuAbrirArchivo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuAbrirArchivoActionPerformed(evt);
            }
        });
        menuArchivo.add(menuAbrirArchivo);

        menuSalir.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
        menuSalir.setText("Salir");
        menuSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuSalirActionPerformed(evt);
            }
        });
        menuArchivo.add(menuSalir);

        barraMenu.add(menuArchivo);

        menuEdicion.setText("Edicion");

        menuEjecutar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_J, java.awt.event.InputEvent.CTRL_MASK));
        menuEjecutar.setText("Ejecutar");
        menuEjecutar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuEjecutarActionPerformed(evt);
            }
        });
        menuEdicion.add(menuEjecutar);

        menuGraficar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_D, java.awt.event.InputEvent.CTRL_MASK));
        menuGraficar.setText("Graficar");
        menuGraficar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuGraficarActionPerformed(evt);
            }
        });
        menuEdicion.add(menuGraficar);

        menuPreferencias.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK));
        menuPreferencias.setText("Preferencias...");
        menuPreferencias.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuPreferenciasActionPerformed(evt);
            }
        });
        menuEdicion.add(menuPreferencias);

        barraMenu.add(menuEdicion);

        setJMenuBar(barraMenu);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void dibujarNodos() {
        EsquemaViajero viajero = ((EjercicioViajero) ejercicio).getViajero();
        Widget nodo;

        grafoViajero = new GrafoViajeroScene();

        for (Punto punto : viajero.getPuntos()) {
            nodo = grafoViajero.addNode(punto);
            nodo.setPreferredLocation(viajero.trasladar(punto, panelDespliegue.getBounds()));
        }

        panelDespliegue.add(grafoViajero.createView(), java.awt.BorderLayout.CENTER);
    }

    private void dibujarGrafo() {
        SolucionViajero solucion = (SolucionViajero) ejercicio.getMejorSolucion();
        Punto anterior = solucion.getRuta().get(0);
        Arco arco;

        dibujarNodos();

        for (Punto punto : solucion.getRuta()) {
            arco = new Arco(anterior.getCostoA(punto));
            grafoViajero.addEdge(arco);
            grafoViajero.setEdgeSource(arco, anterior);
            grafoViajero.setEdgeTarget(arco, punto);
            anterior = punto;
        }
        arco = new Arco(anterior.getCostoA(solucion.getRuta().get(0)));
        grafoViajero.addEdge(arco);
        grafoViajero.setEdgeSource(arco, anterior);
        grafoViajero.setEdgeTarget(arco, solucion.getRuta().get(0));
    }

    private void cargarTablaMochila() {
        MochilaUI mochilaUI = new MochilaUI((EjercicioMochila) ejercicio);
        panelDespliegue.add(mochilaUI, java.awt.BorderLayout.CENTER);
    }

    private void menuSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSalirActionPerformed
        this.dispose();
    }//GEN-LAST:event_menuSalirActionPerformed

    private void menuEjecutarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuEjecutarActionPerformed
        barraProgreso.setValue(0);
        JDialog dialog = new JDialog(this);
        dialog.setTitle("Calculando solución");
        dialog.add(barraProgreso);
        dialog.pack();
        dialog.setModal(true);
        dialog.setLocationRelativeTo(this);
        crearTarea().execute();
        dialog.setVisible(true);
    }//GEN-LAST:event_menuEjecutarActionPerformed

    private void botonAbrirArchivoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonAbrirArchivoActionPerformed
        menuAbrirArchivoActionPerformed(evt);
    }//GEN-LAST:event_botonAbrirArchivoActionPerformed

    private void botonEjecutarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonEjecutarActionPerformed
        menuEjecutarActionPerformed(evt);
    }//GEN-LAST:event_botonEjecutarActionPerformed

    private void menuPreferenciasActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPreferenciasActionPerformed
        ConfiguracionUI panelConfiguracion;
        panelConfiguracion = new ConfiguracionUI(configuracion);
        JDialog dialog = new JDialog();
        dialog.setContentPane(panelConfiguracion);
        dialog.setTitle("Configuración");
        dialog.setModal(true);
        dialog.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
        dialog.pack();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
        if (ejercicio != null) {
            ejercicio.setConfiguracion(configuracion);
        }
    }//GEN-LAST:event_menuPreferenciasActionPerformed

    private void menuAbrirArchivoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuAbrirArchivoActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        File archivo;

        fileChooser.addChoosableFileFilter(new FiltroKNP());
        fileChooser.addChoosableFileFilter(new FiltroTSP());
        fileChooser.addChoosableFileFilter(new FiltroGeneral());
        fileChooser.showOpenDialog(this);

        if ((archivo = fileChooser.getSelectedFile()) == null) {
            return;
        }
        try {
            if (Util.getExtension(archivo).equalsIgnoreCase("tsp")) {
                ejercicio = new EjercicioViajero(archivo);
                dibujarNodos();
            } else if (Util.getExtension(archivo).equalsIgnoreCase("knp")) {
                ejercicio = new EjercicioMochila(archivo);
            } else {
                throw new Exception("Formato de archivo no válido");
            }
            ejercicio.setConfiguracion(configuracion);
        } catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "Error al cargar el archivo:" + ex.getMessage(),
                    "Error en carga",
                    JOptionPane.ERROR_MESSAGE);
        }

    }//GEN-LAST:event_menuAbrirArchivoActionPerformed

    private void menuGraficarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuGraficarActionPerformed
        JDialog dialog = new JDialog();

        Grafica grafica = new Grafica(ejercicio);
        dialog.setContentPane(grafica);
        dialog.setModal(true);
        dialog.pack();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }//GEN-LAST:event_menuGraficarActionPerformed

    private void botonGraficarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonGraficarActionPerformed
        menuGraficarActionPerformed(evt);
    }//GEN-LAST:event_botonGraficarActionPerformed

    private TareaEjecutar crearTarea() {
        TareaEjecutar tarea = new TareaEjecutar(ejercicio);
        tarea.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getNewValue() instanceof StateValue) {
                    StateValue estado = (StateValue) evt.getNewValue();
                    if (estado.equals(StateValue.DONE)) {
                        finalizaEjecucion();
                    }
                } else if (evt.getPropertyName().equals("progress")) {
                    barraProgreso.setValue((Integer) evt.getNewValue());
                }
            }
        });
        return tarea;
    }

    private void finalizaEjecucion() {
        setEstado("Mejor Solucion:" + ejercicio.getMejorSolucion());
        panelDespliegue.removeAll();

        if (ejercicio instanceof EjercicioViajero) {
            dibujarGrafo();
        } else if (ejercicio instanceof EjercicioMochila) {
            cargarTablaMochila();
        }
        SwingUtilities.getWindowAncestor(barraProgreso).dispose();

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
            // Set cross-platform Java L&F (also called "Metal")
            UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());
        } catch (Exception exc) {
        }

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    Simulated frame = new Simulated();
                    frame.setVisible(true);
                    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToolBar barraEstado;
    private javax.swing.JToolBar barraHerramientas;
    private javax.swing.JMenuBar barraMenu;
    private javax.swing.JProgressBar barraProgreso;
    private javax.swing.JButton botonAbrirArchivo;
    private javax.swing.JButton botonEjecutar;
    private javax.swing.JButton botonGraficar;
    private javax.swing.JLabel labelEstado;
    private javax.swing.JMenuItem menuAbrirArchivo;
    private javax.swing.JMenu menuArchivo;
    private javax.swing.JMenu menuEdicion;
    private javax.swing.JMenuItem menuEjecutar;
    private javax.swing.JMenuItem menuGraficar;
    private javax.swing.JMenuItem menuPreferencias;
    private javax.swing.JMenuItem menuSalir;
    private javax.swing.JPanel panelDespliegue;
    private javax.swing.JScrollPane scrollPanelDespliegue;
    // End of variables declaration//GEN-END:variables
}
